"""
分型描述：
fenxing：维护fx,在上涨中，顶分型 low<prelow hogh<prehigh  底分型反之
fenxing0:维护fx,不但要满足分型高低点要求，还要满足close价涨跌的要求  也就是
fenxing_box：维护fx，open close-->low,high 在上涨中 顶分型：1)高点更高，低点更低 2）创新高 但是低点更低  close低 且有一定空间
fenxing_byprice：维护fx,参数gap,price都是bar中的字段；顶分型：反弹gap 下认为底分型，饭反转了
fenxing_byclose：维护fx 参数gap是点数 顶分型：close 反弹gapd点
fenxing_bychan:缠论中的k线合并分型，重在返回fx,low,high  out不需要的地方可以

分型的笔  见bi.py
"""
from research.calcor import calcor_base

class fenxing_bybar(calcor_base):
    def __init__(self,mode="HLC"):
        self.mode=mode#HL,OC,HLC,chan,price,close
        super().__init__(timeperiod=2,datatype="bar")
        self.fx=None
        self.f={"HL":self.calc_HL,
                "OC":self.calc_OC,
                "HLC":self.calc_HLC}
        self.calc=self.f[mode]
    def calc_HL(self):
        prebar=self.hisdata[0]
        b=self.hisdata[1]
        if self.fx is not None:
            if self.fx<=-1:
                if b["high"]>prebar["high"] and b["low"]>prebar["low"]:
                    self.fx=2
                else:
                    self.fx = -1
            elif self.fx>=1:
                if b["high"] < prebar["high"] and b["low"] < prebar["low"]:
                    self.fx = -2
                else:
                    self.fx = 1
        else:
            if b["high"]>prebar["high"] and b["low"]>prebar["low"]:
                self.fx=1
            elif b["high"]<prebar["high"] and b["low"]<prebar["low"]:
                self.fx=-1
        return self.fx
    def calc_OC(self):
        b=self.hisdata[1]
        prebar=self.hisdata[0]
        low=min(b["open"],b["close"])
        high=max(b["open"],b["close"])
        low1 = min(prebar["open"], prebar["close"])
        high1 = max(prebar["open"], prebar["close"])
        if self.fx is not None:
            if self.fx<=-1:
                if high>high1 and low>low1:
                    self.fx=2
                elif high>high1 and low<low1:
                    delta1=high-high1
                    delta2=high1-low1
                    delta3=low1-low
                    if delta1>delta2 and delta1>delta3 and b["open"]<b["close"]:
                        self.fx=2
                    else:
                        self.fx=-1
                else:
                    self.fx = -1
            elif self.fx>=1:
                if high < high1 and low < low1:
                    self.fx = -2
                elif high>high1 and low<low1:
                    delta1=high-high1
                    delta2=high1-low1
                    delta3=low1-low
                    if delta1<delta3 and delta2<delta3 and b["close"]<b["open"]:
                        self.fx=-2
                    else:
                        self.fx=1
                else:
                    self.fx = 1
        else:
            if high>high1 and low>low1:
                self.fx=1
            elif high<high1 and low<low1:
                self.fx=-1
        return self.fx
    def calc_HLC(self):
        prebar = self.hisdata[0]
        b = self.hisdata[1]
        if self.fx is not None:
            if self.fx<=-1:
                if b["high"]>prebar["high"] and b["low"]>prebar["low"] and b["close"]>prebar["close"]:
                    self.fx=2
                else:
                    self.fx = -1
            elif self.fx>=1:
                if b["high"] < prebar["high"] and b["low"] < prebar["low"] and b["close"]<prebar["close"]:
                    self.fx = -2
                else:
                    self.fx = 1
        else:
            if b["high"]>prebar["high"] and b["low"]>prebar["low"] and b["close"]>prebar["close"]:
                self.fx=1
            elif b["high"]<prebar["high"] and b["low"]<prebar["low"] and b["close"]<prebar["close"]:
                self.fx=-1
        return self.fx

class fenxing_byprice_nofresh:
    def __init__(self,price="close",gap=None):
        self.prebar=None
        self.fx=None
        self.gap=gap
        self.price=price
    def oncalc(self,b,timekey=None):
        t0 = b[self.price]
        if self.prebar is not None:

            if self.fx is not None:
                if self.fx<=-1:
                    if self.gap   is not None:
                        t=self.prebar + b[self.gap]
                    else:
                        t=self.prebar
                    if t0>t:
                        self.fx=2
                    else:
                        self.fx = -1
                elif self.fx>=1:
                    if self.gap   is not None:
                        t=self.prebar - b[self.gap]
                    else:
                        t=self.prebar
                    if t0 < t:
                        self.fx = -2
                    else:
                        self.fx = 1
            else:
                if t0>self.prebar:
                    self.fx=1
                elif t0<self.prebar:
                    self.fx=-1
        self.prebar=t0
        return self.fx
class fenxing_byclose_nofresh:
    def __init__(self,gap=0):
        self.prebar=None
        self.fx=None
        self.gap=gap
    def oncalc(self,bar,timekey=None):
        b=bar["close"]
        if self.prebar is not None:
            if self.fx is not None:
                if self.fx<=-1:
                    if b>self.prebar+self.gap:
                        self.fx=2
                    else:
                        self.fx = -1
                elif self.fx>=1:
                    if b < self.prebar-self.gap:
                        self.fx = -2
                    else:
                        self.fx = 1
            else:
                if b>self.prebar:
                    self.fx=1
                elif b<self.prebar:
                    self.fx=-1
        self.prebar=b
        return self.fx

class fenxing_bychan_nofresh:
    def __init__(self):
        self.fx=0
        self.prebar=[None,None]

    def oncalc(self, b,timekey=None):
        if self.fx>=1:#涨  找顶分型
            low=b["low"]
            high=b["high"]
            if low>=self.prebar[0] and high>=self.prebar[1]:#高低点都高
                self.prebar = [low, high]
            elif low<self.prebar[0] and high<self.prebar[1]:#顶分型   高低点都低
                self.fx = -2
                self.prebar = [low, high]
            elif low>=self.prebar[0] and high<=self.prebar[1]:#内包含
                self.prebar[0]=low
            elif low<=self.prebar[0] and high>=self.prebar[1]:#外包含
                self.prebar[1]=high
        elif self.fx<=-1:#跌 找底分型
            low = b["low"]
            high = b["high"]
            if low <= self.prebar[0] and high <= self.prebar[1]:  # 高低点都低
                self.prebar = [low, high]
            elif low > self.prebar[0] and high > self.prebar[1]:  # 底分型   高低点都高
                self.fx = 2
                self.prebar = [low, high]
            elif low >= self.prebar[0] and high <= self.prebar[1]:  # 内包含
                self.prebar[1] = high
            elif low <= self.prebar[0] and high >= self.prebar[1]:  # 外包含
                self.prebar[0] = low
        else:
            if b["open"]<b["close"]:
                self.fx=1
            else:
                self.fx=-1
            self.prebar=[b["low"],b["high"]]

        return self.fx,self.prebar[0],self.prebar[1]

